﻿package org.hive.managers.plugin
{
	
	import flash.display.*;
	import flash.geom.Rectangle;
	
	import org.hive.Hive;
	import org.hive.events.*;
	import org.hive.managers.*;
	import org.hive.managers.utils.LayoutArrangement;
	import org.hive.sequence.ActionSequence;
	import org.hive.sequence.CloseSequence;
	import org.hive.sequence.Sequence;
	
	public class LayoutManager extends Manager
	{
        //________________________________________________ PROPERTIES
       
		private var _canvas : DisplayObjectContainer;
		private var _canvasWidth : Number = 0;
		private var _canvasHeight : Number = 0;
		

		//________________________________________________ CONSTRUCTOR
		
		public function LayoutManager(hive:Hive):void
		{
			super(hive);
		}
		
		public static function init(hive:Hive,canvas:DisplayObjectContainer=null):LayoutManager
		{
			if(Hive.DEBUG_MODE){trace( "LayoutManager :: init" )}

			var manager:LayoutManager = new LayoutManager(hive);
			hive.registerManager(manager);
			
			//_____________ Register Object :: DisplayObject
			function displayObjectFunc( action:*, sequence:Sequence, positionInSequence:int ):void {
			    if( sequence is ActionSequence ){
    				if( sequence.getParams(action) != null){
    					manager.addChildAt( action, sequence.getParams(action)[0] );
    				} else manager.addChild(action);
    			}
    			else if( sequence is CloseSequence )
    			{
    			    if( action is DisplayObject && manager.contains(action as DisplayObject) )
    			    manager.removeChild(action as DisplayObject);
    			}
			}
			hive.sequenceManager.registerAction(DisplayObject, displayObjectFunc);

			manager._canvas = canvas || hive.canvas;
			return manager;
		}
		

		

		
       
		//________________________________________________ DISPLAY LIST METHODS
        public function autoAlign( child:DisplayObject, alignment:String ):void
        {
            
        }


        /**
        *
        * @param	element
        * @param	index
        * @return
        */
		private function buildElement( element:*, index:int=0 ):DisplayObject
		{
			if( index ){
				return _canvas.addChildAt( element, index );
			}else{
				return _canvas.addChild( element );
			}
		}
		
        /**
        *
        * @param	arrangement
        * @param	target
        * @param	relativeTo
        */
		public function arrange( arrangement:String, target:DisplayObject, relativeTo:DisplayObject=null ):*
		{
			if( !_canvas.contains( target ) ) return null;
			
			var index:Number = -1;
			switch( arrangement ){
				
				case LayoutArrangement.BRING_TO_BACK:
					index = 0
				break;
				
				case LayoutArrangement.BRING_TO_FRONT:
					index = _canvas.numChildren - 1;
				break;
				
				case LayoutArrangement.BRING_BACKWARD:
					index = _canvas.getChildIndex( target ) - 1;
				break;
				
				case LayoutArrangement.BRING_FORWARD:
					index = _canvas.getChildIndex( target ) + 1;
				break;
				
				case LayoutArrangement.BEHIND:
					index = _canvas.getChildIndex( relativeTo ) - 1;
				break;
				
				case LayoutArrangement.INFRONT:
					index = _canvas.getChildIndex( relativeTo ) + 1;
				break;
			}
			
			if( index != -1 )	_canvas.setChildIndex( target, index );
			
			return index;
		}

        public var viewportRect:Rectangle = new Rectangle(0,0,900,680);

        /**
        *
        * @param	child
        * @return
        */
		public function getChildIndex( child:DisplayObject ):int
		{
			return _canvas.getChildIndex( child );
		}

        /**
        *
        * @param	child
        * @return
        */
		public function addChild( child:DisplayObject ):DisplayObject
		{
			return buildElement( child );
		}
		
        /**
        *
        * @param	child
        * @param	index
        * @return
        */
		public function addChildAt( child:DisplayObject, index:int=0 ):DisplayObject
		{
			return buildElement( child, index );
		}
		
        /**
        *
        * @param	...children
        * @return
        */
		public function removeChildren( ...children ):void
		{
			for each( var child:DisplayObject in children ) removeChild( child );
		}
		
        /**
        *
        * @param	child
        * @return
        */
		public function removeChild( child:DisplayObject ):DisplayObject
		{
			return _canvas.removeChild( child );
		}
		
        /**
        *
        * @param	index
        * @return
        */
		public function removeChildAt( index:Number ):DisplayObject
		{
			return _canvas.removeChildAt( index );
		}
		
		public function container( child:DisplayObject ):Boolean
		{
		    return _canvas.contains(child);
		}

        /**
        *
        * @param	name
        * @return
        */
		public function getChildByName( name:String ):DisplayObject
		{
			return _canvas.getChildByName( name );
		}
		
        /**
        *
        * @param	index
        * @return
        */
		public function getChildAt( index:Number ):DisplayObject
		{
			return _canvas.getChildAt( index );
		}
		
        /**
        *
        * @return
        */
		public function get documentClass( ):DisplayObject
		{
			return _canvas.loaderInfo.content;
		}
		
        /**
        *
        * @return
        */
		public function get stageWidth( ):Number
		{
			return _canvas.stage.stageWidth;
		}
		
        /**
        *
        * @return
        */
		public function get stageHeight( ):Number
		{
			return _canvas.stage.stageHeight;
		}
		
        /**
        *
        * @return
        */
		public function get stage( ):Stage
		{
			return _canvas.stage;
		}
		
        /**
        *
        * @param	child
        * @return
        */
		public function contains( child:DisplayObject ):Boolean
		{
			return _canvas.contains(child);
		}

        /**
        *
        * @return
        */
        public function get stageLeft( ):Number
        {
            return (viewportRect.width - stageWidth) >> 1;
        }

        /**
        *
        * @return
        */
        public function get stageRight( ):Number
        {
            return viewportRect.width + Math.abs(stageLeft);
        }
		
        /**
        *
        * @return
        */
		public function get stageCenterX( ):Number
		{
			return viewportRect.width >> 1;
		}
		
        /**
        *
        * @return
        */
		public function get stageCenterY( ):Number
		{
			return viewportRect.height >> 1;
		}

        /**
        *
        * @return
        */
        public function get stageTop( ):Number
        {
            return 0;
        }

        /**
        *
        * @return
        */
        public function get stageBottom( ):Number
        {
            return stageHeight;
        }
		
		
		/**
        *
        */
		public var blocked		: Boolean = false;
		
		/**
        *
        * 
        */
		public function blockInteraction():void
		{
			blocked = true;
			_canvas.mouseEnabled = false;
			_canvas.tabEnabled = false;
		}
		
		/**
        *
        * 
        */
		public function unblockInteraction():void
		{
			blocked = false;
            _canvas.mouseEnabled = true;
            _canvas.tabEnabled = true;
		}
				
	}
}
